package com.sengled.cloud.biz.union.mgt.api.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sengled.cloud.biz.union.mgt.model.request.LoginRequestFilterVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * Created by ti on 2017/8/2.
 */
//@Component
public class JsonAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private boolean postOnly;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException{
        System.out.println("attemptAuthentication");
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        UsernamePasswordAuthenticationToken authRequest = null;
        try {
            authRequest = this.getUserNamePasswordAuthenticationToken(request);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
    }

    /**
     * @param request
     * @return
     */
    private UsernamePasswordAuthenticationToken getUserNamePasswordAuthenticationToken(HttpServletRequest request) throws IOException {

        //login form
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if(StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)){
            return new UsernamePasswordAuthenticationToken(username, password);
        }

        //login json
        StringBuffer sb = new StringBuffer();
        BufferedReader bufferedReader = null;
        String content = "";
        LoginRequestFilterVo sr = null;

        try {
            bufferedReader =  request.getReader();
            char[] charBuffer = new char[128];
            int bytesRead;
            while ( (bytesRead = bufferedReader.read(charBuffer)) != -1 ) {
                sb.append(charBuffer, 0, bytesRead);
            }
            content = sb.toString();
            ObjectMapper objectMapper = new ObjectMapper();
            try{
                sr = objectMapper.readValue(content, LoginRequestFilterVo.class);
            }catch(Throwable t){
                throw new IOException(t.getMessage(), t);
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        request.setAttribute("biz-union-user-channel",sr.getChannel());
        request.setAttribute("biz-union-user-osType",sr.getOs_type());
        request.setAttribute("biz-union-user-uuid",sr.getUuid());
        request.setAttribute("biz-union-user-username",sr.getUsername());
        request.setAttribute("biz-union-user-password",sr.getPassword());
        sr.setUsername(sr.getChannel()+"-#-"+sr.getUsername());
        return new UsernamePasswordAuthenticationToken(sr.getUsername(), sr.getPassword());
    }

}
